package com.changzhi.service.impl;

import com.alibaba.fastjson.JSON;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.changzhi.common.constans.Constants;
import com.changzhi.common.constans.RedisConstans;
import com.changzhi.common.exception.ServiceException;
import com.changzhi.common.util.DateUtil;
import com.changzhi.ldyl.model.*;
import com.changzhi.ldyl.model.vo.UserVo;
import com.changzhi.mapper.ActivityPrizeMapper;
import com.changzhi.mapper.ActivityRecordMapper;
import com.changzhi.service.ActivityService;
import com.changzhi.service.GiftService;
import com.changzhi.service.UserService;
import com.changzhi.service.WeekStarService;
import com.changzhi.util.CommonUtil;
import com.changzhi.util.RedisUtil;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.lang3.StringUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.util.CollectionUtils;

import javax.annotation.PostConstruct;
import javax.annotation.Resource;
import java.time.LocalDateTime;
import java.util.*;
import java.util.stream.Collectors;

/**
 * @Description:
 * @author: 小落
 * @date: 2021年03月16日
 */
@Slf4j
@Service
public class WeekStarServiceImpl implements WeekStarService {

	@Autowired private ActivityService activityService;
	@Autowired private UserService userService;
	@Autowired private RedisUtil redisUtil;
	@Resource private ActivityRecordMapper activityRecordMapper;
	@Autowired private GiftService giftService;
	@Resource private ActivityPrizeMapper activityPrizeMapper;

	public final static Map<String, LocalDateTime> TIME_MAP = new HashMap<>();
	public final static Map<Integer, String> TYPE_MAP = new HashMap<>();
	public final static Integer ACTIVITY_ID = 27;

	@PostConstruct public void init() {
		redisUtil.del(RedisConstans.ACTIVITY + ACTIVITY_ID);
		Activity activity2 = activityService.getActivity(ACTIVITY_ID);
		List<ActivityPrize> prizeList = activityService
				.getPrizeList(ACTIVITY_ID, null);
		for (ActivityPrize activityPrize : prizeList) {
			if (activityPrize.getType() == 3) {
				continue;
			}
			TYPE_MAP.put(activityPrize.getType(), activityPrize.getIcon());
		}
		//存活动时间
		TIME_MAP.put("startTime", activity2.getStartTime());
		TIME_MAP.put("endTime", activity2.getEndTime());
	}

	@Override
	public void doMqDataByUserGift(UserGift userGift) {
		//1.是否在活动时间内
		if (!DateUtil.isBetweenTime(TIME_MAP.get("startTime"),
				TIME_MAP.get("endTime"))) {
			//测试账号通行
			if (!CommonUtil.getTestAccountList()
					.contains(userGift.getUserId())) {
				return;
			}
		}
		//2.指定礼物
		Map<Integer, Integer> map = activityService
				.someGiftIdList(ACTIVITY_ID, null);
		Integer type = map.get(userGift.getGiftId());
		if (type == null) {
			return;
		}
		String userId = userGift.getUserId();
		String targetId = userGift.getTargetId();
		Integer giftId = userGift.getGiftId();
		Integer giftCount = userGift.getGiftCount();
		//3.增加收礼用户礼物数量
		String key1 = RedisConstans
				.putRediskey(RedisConstans.ACTIVITY_FLAG, ACTIVITY_ID, targetId,
						type);
		Integer recordId1 = redisUtil.get(key1);
		if (recordId1 == null) {
			ActivityRecord record = new ActivityRecord();
			record.setActivityId(ACTIVITY_ID);
			record.setType(type);
			record.setUserId(targetId);
			record.setGiftId(giftId);
			record.setNum(giftCount);
			activityRecordMapper.insert(record);
			redisUtil.set(key1, record.getId(), RedisConstans.ONE_MONTH);
		} else {
			activityRecordMapper.addNum(recordId1, giftCount);
		}
		//删除排行榜缓存
		getRankingsByDb(type);
		//4.增加送礼用户礼物数量
		type += 3;
		String key2 = RedisConstans
				.putRediskey(RedisConstans.ACTIVITY_FLAG, ACTIVITY_ID, userId,
						type);
		Integer recordId2 = redisUtil.get(key2);
		if (recordId2 == null) {
			ActivityRecord record = new ActivityRecord();
			record.setActivityId(ACTIVITY_ID);
			record.setType(type);
			record.setUserId(userId);
			record.setGiftId(giftId);
			record.setNum(giftCount);
			activityRecordMapper.insert(record);
			redisUtil.set(key2, record.getId(), RedisConstans.ONE_MONTH);
		} else {
			activityRecordMapper.addNum(recordId2, giftCount);
		}
		//删除排行榜缓存
		Integer finalType = type;
		List<UserVo> list = activityRecordMapper
				.selectNumRankings(ACTIVITY_ID, finalType);
		redisUtil.set(RedisConstans
				.putRediskey(RedisConstans.WEEK_START_RANKING, ACTIVITY_ID,
						finalType), list, RedisConstans.ONE_HOUR);
	}

	private List<UserVo> getRankingsByDb(Integer type) {
		List<UserVo> list = activityRecordMapper
				.selectNumRankings(ACTIVITY_ID, type);
		redisUtil.set(RedisConstans
				.putRediskey(RedisConstans.WEEK_START_RANKING, ACTIVITY_ID, type), list, RedisConstans.ONE_HOUR);
		return list;
	}

	@Override public Map<String, Object> rankings(String userId, Integer type) {
		Map<String, Object> result = new HashMap<>();
		//排行榜
		List<UserVo> list = redisUtil.get(RedisConstans
				.putRediskey(RedisConstans.WEEK_START_RANKING, ACTIVITY_ID, type));
		if (CollectionUtils.isEmpty(list)) {
			list = getRankingsByDb(type);
		}
		int rank = 1;
		int previousNum = 0;
		UserVo userVo = null;
		for (UserVo vo : list) {
			vo.setRank(rank).setGiftUrl(TYPE_MAP.get(type % 3));
			if (userId.equals(vo.getUserId())) {
				userVo = vo;
				if (rank != 1) {
					userVo.setValue(previousNum - vo.getNum());
				}
			}
			if (StringUtils.isBlank(vo.getAvatarUrl())) {
				vo.setAvatarUrl(Constants.DEFAULT_AVATAR);
			}
			previousNum = vo.getNum();
			rank += 1;
		}

		//个人信息
		if (userVo == null) {
			userVo = new UserVo();
			User user = userService.getUser(userId);
			LambdaQueryWrapper<ActivityRecord> wrapper = new LambdaQueryWrapper<>();
			wrapper.eq(ActivityRecord::getActivityId, ACTIVITY_ID)
					.eq(ActivityRecord::getType, type)
					.eq(ActivityRecord::getUserId, userId);
			ActivityRecord record = activityRecordMapper.selectOne(wrapper);
			userVo.setUserId(user.getUserId()).setAccountId(user.getAccountId())
					.setNickname(user.getNickname()).setAvatarUrl(StringUtils.isBlank(user.getAvatarUrl()) ?
					Constants.DEFAULT_AVATAR :
					user.getAvatarUrl())
					.setGiftUrl(TYPE_MAP.get(type % 3))
					.setNum(record == null ? 0 : record.getNum())
					//若在对应榜单上则显示实际名次“1-50”距上一名还差xxx；若未上榜则显示“未上榜”，距上榜还差xxx。
					.setValue(previousNum - (record == null ? 0 : record.getNum())).setRank(-1);
		}
		if (userVo.getValue() != null && userVo.getValue() == 0) {
			userVo.setValue(1);
		}
		//返回
		result.put("ranking", list);
		result.put("self", userVo);
		return result;
	}

	@Override
	public void givePrize() {
		LambdaQueryWrapper<ActivityPrize> prizeWrapper = new LambdaQueryWrapper<>();
		prizeWrapper.eq(ActivityPrize::getActivityId, ACTIVITY_ID)
				.ge(ActivityPrize::getType, 3);
		List<ActivityPrize> prizeList = activityPrizeMapper.selectList(prizeWrapper);
		if (CollectionUtils.isEmpty(prizeList)) {
			throw new ServiceException("奖品不存在");
		}
		Map<String, Integer> decorateMap = new HashMap<>();
		List<UserVo> dressList = new ArrayList<>();
		for (int i = 0; i < 6; i++) {
			LambdaQueryWrapper<ActivityRecord> wrapper = new LambdaQueryWrapper<>();
			wrapper.eq(ActivityRecord::getActivityId, ACTIVITY_ID).eq(ActivityRecord::getType, i);
			wrapper.orderByDesc(ActivityRecord::getNum).last("limit 10");
			List<ActivityRecord> recordList = activityRecordMapper.selectList(wrapper);
			int count = 1;
			for (ActivityRecord record : recordList) {
				//是否已发放
				LambdaQueryWrapper<ActivityRecord> queryWrapper = new LambdaQueryWrapper<>();
				queryWrapper.eq(ActivityRecord::getActivityId, ACTIVITY_ID)
						.eq(ActivityRecord::getUserId, record.getUserId())
						.eq(ActivityRecord::getType, 7).last("limit 1");
				if (activityRecordMapper.selectOne(queryWrapper) != null) {
					//continue;
				}
				//装饰
				Integer mutip = decorateMap.get(record.getUserId());
				if (mutip == null) {
					decorateMap.put(record.getUserId(), 1);
				} else {
					decorateMap.put(record.getUserId(), mutip + 1);
				}
				//装扮,第一名,魅力
				if (count == 1 && i < 3) {
					dressList.add(new UserVo(record.getUserId(),
							prizeList.stream().filter(p -> p.getType() == 4).collect(Collectors.toList()).get(0)
									.getGiftId()));
					dressList.add(new UserVo(record.getUserId(),
							prizeList.stream().filter(p -> p.getType() == 5).collect(Collectors.toList()).get(0)
									.getGiftId()));
				}
				if (count == 1 && i >= 3) {
					dressList.add(new UserVo(record.getUserId(),
							prizeList.stream().filter(p -> p.getType() == 6).collect(Collectors.toList()).get(0)
									.getGiftId()));
					dressList.add(new UserVo(record.getUserId(),
							prizeList.stream().filter(p -> p.getType() == 7).collect(Collectors.toList()).get(0)
									.getGiftId()));
				}
				count++;
			}
		}
		//保存装饰
		log.warn("methodName:givePrize, 装饰奖励={}", JSON.toJSONString(decorateMap));
		ActivityPrize prize1 = prizeList.stream().filter(p -> p.getType() == 3).collect(Collectors.toList()).get(0);
		Set<Map.Entry<String, Integer>> entries = decorateMap.entrySet();
		for (Map.Entry<String, Integer> entry : entries) {
			giftService.saveUserDress(ACTIVITY_ID, entry.getKey(), prize1.getGiftId(), 7, entry.getValue(), "7月周星榜获得");
		}
		//保存装扮
		log.warn("methodName:givePrize, 装扮奖励={}", JSON.toJSONString(decorateMap));
		for (UserVo userVo : dressList) {
			giftService.savePrize(ACTIVITY_ID, userVo.getUserId(), userVo.getGiftId(), 8, 1);
		}

	}

}